﻿using FastDFSCore;
using FastDFSCore.Protocols;
using FileStorageCenter.Services.Models;
using Microsoft.Extensions.Options;

namespace FileStorageCenter.Services.FileStorageProvider.FastDFS;

public class FastDFSProvider : IFileStorageProvider
{
    private readonly IFastDFSClient _client;
    private readonly FastDFSContainerOptions _options;

    public FastDFSProvider(IFastDFSClient client, IOptions<FastDFSContainerOptions> options)
    {
        _client = client;
        _options = options.Value;
    }

    public async ValueTask<byte[]> DownloadFileAsync(string groupName, string fileid, string clusterName = "")
    {
        var storageNode = await _client.GetStorageNodeAsync(groupName, clusterName);
        storageNode.ConnectionAddress.IPAddress = _options.IPAddress;

        return await _client.DownloadFileAsync(storageNode, fileid, clusterName);
    }

    public async ValueTask<FastDFSFileInfo> GetFileInfo(string groupName, string fileid, string clusterName = "")
    {
        var storageNode = await _client.GetStorageNodeAsync(groupName, clusterName);

        var result = await _client.GetFileInfo(storageNode, fileid, clusterName);

        return result;
    }

    public async ValueTask<StorageNode> GetStorageNodeAsync(string groupName, string fileid, string clusterName = "")
    {
        var result = await _client.GetStorageNodeAsync(groupName, clusterName);

        return result;
    }

    public string GetToken(string fileid, string clusterName = "", DateTime? dateTime = null)
    {
        return _client.GetToken(fileid, dateTime, clusterName);
    }

    public async ValueTask<IReadOnlyCollection<GroupInfo>> ListAllGroupInfosAsync(string clusterName)
    {
        var result = await _client.ListAllGroupInfosAsync(clusterName);

        return result.AsReadOnly();
    }

    public async ValueTask<GroupInfo> ListOneGroupInfoAsync(string groupName, string clusterName = "")
    {
        var result = await _client.ListOneGroupInfoAsync(groupName, clusterName);

        return result;
    }

    public async ValueTask<IReadOnlyCollection<StorageInfo>> ListStorageInfosAsync(string groupName, string clusterName = "")
    {
        var result = await _client.ListStorageInfosAsync(groupName, clusterName);

        return result.AsReadOnly();
    }

    public async ValueTask<StorageNode> QueryStorageNodeForFileAsync(string groupName, string fileid, string clusterName = "")
    {
        var result = await _client.QueryStorageNodeForFileAsync(groupName, fileid, clusterName);

        return result;
    }

    public async ValueTask<IReadOnlyCollection<StorageNode>> QueryStorageNodesForFileAsync(string groupName, string fileid, string clusterName = "")
    {
        var result = await _client.QueryStorageNodesForFileAsync(groupName, fileid, clusterName);

        return result.AsReadOnly();
    }

    public async ValueTask<bool> RemoveFileAsync(string groupName, string fileid, string clusterName = "")
    {
        try
        {
            var result = await _client.RemoveFileAsync(groupName, fileid, clusterName);

            return result;
        }
        catch (Exception)
        {
            return false;
        }
    }

    public async ValueTask<string> UploadFileAsync(UploadModel model)
    {
        var storageNode = await _client.GetStorageNodeAsync(_options.GroupName, _options.ClusterName);

        storageNode.ConnectionAddress.IPAddress = _options.IPAddress;

        var result = await _client.UploadFileAsync(storageNode, model.Buffer, model.Extension, _options.ClusterName);

        return result;
    }
}